package cn.tedu.v3_1;

import java.io.*;
import java.net.*;
import java.util.*;

/**
 * 聊天室  Version3.1
 * 优化版本 功能：客户端与服务器端可以双向沟通
 *优化1：导入包优化  通配符
 * 优化2：动态的数据全部封装到类上  代码更加易用
 * 优化3：读入和写出  操作定义---构造器  |  功能
 *    构造器主要用于对象初始化 Client对象初始化：添加ip和端口号
 *                                         创建流添加
 *    优点：1.减少代码重复和复杂度
 *         2.代码的结构清晰
 *         3.客户端在创建之初  明确具备读写
 *    构造器：读写定义
 *    start 方法：保留读写功能
 *
 * 问题1：标准IO 流置空  线程中使用BufferedRead  无法到达【作用域不够】
 * 流置空的问题更适合在短期  简单场景中使用 不一定保证对象正确释放
 ** 有可能报出null，实际软件开发中使用JavaOOP封装思路替换置空方式
 * * 置空流方式      升级
 * * JavaOOP封装方式：流私化属性：流  IP    socket
 * * 好处：①数据保护：本类下可以访问，确保其他类无法直接访问
 * *      ②易用性和安全性：置空操作--目的：赋值、关闭、紧邻try上
 * *      私有化属性-->便与修改，流争取的关闭
 *
 */
public class Client {
    //优化2：把所有的动态数据 全部进行私有化到类上 ---方便修改
    private static  final String HOST="192.168.59.17";
    private static  final Integer PORT=1234;
    private Socket socket;
    //1.私有化IP
    private String ip;
    //1.置空流   升级 java oop  封装 ---私有化属性 ：本类任意地方都可以使用
    private PrintWriter pw;
    private BufferedReader br;
    public Client(){
        try {
            socket=new Socket(HOST,PORT);
            ip=socket.getInetAddress().getHostAddress();
            br=new BufferedReader(new InputStreamReader(socket.getInputStream(),"UTF8"));
            pw=new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(),"UTF8")),true);
            //2.确定传入IP就是当前的地址
        }catch (SocketException e){
            System.out.println();
        } catch(UnknownHostException e){
            System.out.println("IP地址有问题 请询问服务器端");
        } catch (IOException e) {
            System.out.println("客户端主动退出：断开连接");
        }
    }
    public void start(){
        try {
            //1.2读入操作
            new Thread(() -> {
                try {
                    //1.4  线程中--创建变量--接收服务器端发来的文本
                    String message;
                    //1.5一直接收客户发来的消息
                    while ((message = br.readLine()) != null) {
                        System.out.println("客户端说：" + message);
                        //1.6增加一句---每次客户端发给服务器端内容
                        System.out.println("客户端请输入：");
                    }
                } catch (UnsupportedEncodingException e) {
                    System.out.println();
                } catch (SocketException e) {
                    System.out.println();
                } catch (IOException e) {
                    System.out.println("服务器端发来的消息断开了");
                }
            }).start();

            System.out.println("客户端请输入：");
            Scanner input = new Scanner(System.in);   //测试----控制台输入文本
            while (true) {//死循环---一直与服务器说话
                String say = input.nextLine();
                pw.println("客户端说：" + say);  //写出   一行行文字
                System.out.println("客户端请输入：");
            }
        }finally {
            if (br!=null)
                try {
                    br.close();
                } catch (IOException e) {
                    System.out.println("服务器通讯失败");
                }
            //关闭流 关闭socket
            if (pw!=null)
                pw.close();
            if (socket!=null&&!socket.isClosed()){
                System.out.println("客户端关闭成功");
                try {
                    socket.close();
                } catch (IOException e) {
                    System.out.println("客户端关闭失败");
                }
            }
        }
        //读入
      /*  while (true){
            String str=br.readLine();
            System.out.println(str);
        }*/
    }
   public static void main(String[] args)  {
       new Client().start();
   }
}
